package com.example.pdftoofd.service;

import com.alibaba.fastjson.JSONObject;
import com.example.pdftoofd.entity.HistoryEntity;
import com.example.pdftoofd.result.BaseResult;
import com.example.pdftoofd.utils.MyFileUtil;
import com.spire.pdf.FileFormat;
import com.spire.pdf.PdfDocument;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.ofdrw.tool.merge.OFDMerger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.PostConstruct;
import java.io.File;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;

@Component
public class PDFConvertOFDService {
    @Value("${filePath.root:./file}")
    private String root;

    @Value("${filePath.root:./file}" + "${filePath.pdf:/pdf}")
    private String pdfPath;

    @Value("${filePath.root:./file}" + "${filePath.ofd:/ofd}")
    private String ofdPath;

    @Value("${filePath.root:./file}" + "${filePath.ofd-split:/ofd-split}")
    private String ofdSplitPath;

    @Autowired
    private HistoryService historyService;

    @PostConstruct
    public void init() {
        MyFileUtil.ifNotExistsAndMkdir(ofdPath);
    }

    public String execute(MultipartFile pdf) throws IOException {
        MyFileUtil.ifExistsAndDelete(ofdPath, false);
        String pdfName = pdf.getOriginalFilename().replaceAll("\\..*", "");
        try {
            String splitPdfPath = splitPdfOnOne(pdf, pdfPath, pdfName);
            String splitOfdPath = pdfToOfd(splitPdfPath, pdfName);
            String ofdMergePath = mergeOfd(splitOfdPath, pdfName);
            historyService.writeHistory(JSONObject.toJSONString(HistoryEntity.success(pdfName, new Date())));
            MyFileUtil.ifExistsAndDelete(splitPdfPath, true);
            MyFileUtil.ifExistsAndDelete(splitOfdPath, true);
            return ofdMergePath;
        } catch (IOException e) {
            historyService.writeHistory(JSONObject.toJSONString(HistoryEntity.fail(pdfName, new Date(), e.getMessage())));
            throw new IOException(e);
        }
    }

    public BaseResult execute(MultipartFile pdf, boolean bool) {
        String pdfName = pdf.getOriginalFilename().replaceAll("\\..*", "");
        try {
            String splitPdfPath = splitPdfOnOne(pdf, pdfPath, pdfName);
            String splitOfdPath = pdfToOfd(splitPdfPath, pdfName);
            String ofdMergePath = mergeOfd(splitOfdPath, pdfName);
            return BaseResult.success().message(ofdMergePath);
        } catch (IOException e) {
            e.printStackTrace();
            return BaseResult.fail("转换失败");
        }
    }

    public String splitPdfOnOne(MultipartFile sourceFile, String targetPath, String pdfName) throws IOException {
        targetPath = targetPath + pdfName;
        MyFileUtil.ifNotExistsAndMkdir(targetPath);
        try (PDDocument document = PDDocument.load(sourceFile.getInputStream())) {
            int pageSize = document.getNumberOfPages();
            PDPage page = null;
            String splitName = null;
            for (int i = 0; i < pageSize; i++) {
                try (PDDocument doc = new PDDocument()) {
                    splitName = i + ".pdf";
                    page = document.getPage(i);
                    doc.addPage(page);
                    File outFile = new File(targetPath, splitName);
                    doc.save(outFile);
                } catch (IOException e) {
                    throw new IOException("切割pdf异常");
                }
            }
        } catch (IOException e) {
            throw new IOException("切割pdf异常");
        }
        return targetPath;
    }

    public String pdfToOfd(String splitPdfPath, String pdfName) {
        String splitOfdPath = ofdSplitPath + pdfName;
        MyFileUtil.ifNotExistsAndMkdir(splitOfdPath);
        File[] files = new File(splitPdfPath).listFiles();
        for (File file : files) {
            PdfDocument pdf = new PdfDocument();
            pdf.loadFromFile(file.getAbsolutePath());
            pdf.saveToFile(splitOfdPath + "/" + file.getName().replaceAll("pdf", "ofd"), FileFormat.OFD);
        }
        return splitOfdPath;
    }

    public String mergeOfd(String splitOfdPath, String pdfName) {
        List<String> FileNames = Arrays.asList(new File(splitOfdPath).list());
        Collections.sort(FileNames, (o1, o2) ->
                Integer.valueOf(o1.replaceAll("\\..*", "")).compareTo(Integer.valueOf(o2.replaceAll("\\..*", "")))
        );
        // 1. 提供合并文件输出位置。
        String ofdMergePath = ofdPath + pdfName + ".ofd";
        Path dst = Paths.get(ofdMergePath);
        // 3. 创建合并对象
        try (OFDMerger ofdMerger = new OFDMerger(dst)) {
            for (String ofdPart : FileNames) {
                ofdMerger.add(Paths.get(splitOfdPath + "/" + ofdPart), 1);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return ofdMergePath;
    }
}
